package com.cbh.binlog.link;

import com.cbh.binlog.core.SchemaParser;
import com.cbh.binlog.entity.BinaryLogEventCallback;
import com.github.shyiko.mysql.binlog.event.EventType;
import org.springframework.util.AntPathMatcher;

/**
 * Binlog事件监听器 接口
 *
 * @author ChenBiHui
 * @date 2025/1/16
 */
public interface BinaryLogEventListener {

    String DOL = ".";
    AntPathMatcher ANT = new AntPathMatcher(DOL);

    /**
     * 设置迭代处理器
     */
    void setNext(BinaryLogEventListener callback);

    /**
     * 迭代处理器
     *
     * @return 回调实现
     */
    BinaryLogEventListener next();

    /**
     * 监听库
     *
     * @return 库名(Ant匹配模式 / 静态生成)
     */
    String schema();

    /**
     * 监听表
     *
     * @return 表名(静态生成)
     */
    String table();

    /**
     * 写入事件 回调
     *
     * @param callback 入参
     */
    void write(BinaryLogEventCallback callback);

    /**
     * 更新事件 回调
     *
     * @param callback 入参
     */
    void update(BinaryLogEventCallback callback);

    /**
     * 删除事件 回调
     *
     * @param callback 入参
     */
    void delete(BinaryLogEventCallback callback);

    /**
     * 默认方法 - 匹配模型
     *
     * @param eventType 事件类型
     * @param schema    库
     * @param table     表
     * @param callback  回调对象
     */
    default void process(EventType eventType, String schema, String table, BinaryLogEventCallback callback) {
        String current = SchemaParser.compose(this.schema(), this.table());
        String target = SchemaParser.compose(schema, table);
        if (ANT.match(current, target)) {
            if (EventType.isWrite(eventType)) {
                this.write(callback);
                return;
            }
            if (EventType.isUpdate(eventType)) {
                this.update(callback);
                return;
            }
            if (EventType.isDelete(eventType)) {
                this.delete(callback);
                return;
            }
        }
        BinaryLogEventListener next = this.next();
        if (next == null) {
            return;
        }
        next.process(eventType, schema, table, callback);
    }
}
